package com.example.yckjbigdataservice.config;

import com.huawei.jredis.client.GlobalConfig;
import com.huawei.jredis.client.SslSocketFactoryUtil;
import com.huawei.jredis.client.auth.AuthConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import javax.net.ssl.SSLSocketFactory;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;

@Configuration
@Slf4j
public class RedisConfig {

    protected static final Logger logger = LoggerFactory.getLogger(RedisConfig.class.getName());

    /**
     * 默认连接超时时间
     */
    private static final Integer TIMEOUT = 3000;

    /**
     * 最大重试次数
     */
    private static final Integer MAX_ATTEMPTS = 1;

    @Value("${custom.redis.cluster.nodes}")
    private String nodes;

    @Value("${custom.redis.keytab}")
    private String keytab;

    @Value("${custom.redis.user}")
    private String user;

    @Value("${custom.redis.krb5}")
    private String krb5;

    @Value("${custom.redis.realm}")
    private String realm;

    @Value("${custom.redis.ssl}")
    private boolean ssl;

    @Bean
    public JedisCluster jedisCluster() {
        System.setProperty("redis.authentication.jaas", "true");
        AuthConfiguration authConfig = new AuthConfiguration(krb5, keytab, user);
        GlobalConfig.setAuthConfiguration(authConfig);
        authConfig.setServerRealm(realm);
        authConfig.setLocalRealm(realm);

        //logger.info("user={}, realm={}", user, realm);

        // 配置连接池
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(5);
        jedisPoolConfig.setMaxIdle(3);
        jedisPoolConfig.setMinIdle(2);

        Set<HostAndPort> hosts = new HashSet<HostAndPort>();
        for (String node : nodes.split(",")) {
            HostAndPort hp = getIpAndPort(node);

            if (hp == null) {
                logger.warn("{} not valid", node);
                continue;
            }
            //log.info("循环 host={}, port={}", hp.getHost(), hp.getPort());
            hosts.add(hp);
        }
        final SSLSocketFactory socketFactory;
        try {
            socketFactory = SslSocketFactoryUtil.createTrustALLSslSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            throw new RuntimeException(e);
        }
        return new JedisCluster(hosts, TIMEOUT, TIMEOUT, TIMEOUT, MAX_ATTEMPTS, jedisPoolConfig, ssl,
                socketFactory, authConfig);

    }

    public static HostAndPort getIpAndPort(String hostAndPortStr) {
        if (StringUtils.isBlank(hostAndPortStr)) {
            return null;
        }
        String[] hostAndPort = hostAndPortStr.split(":");
        String ipAddr;
        String port;
        if (hostAndPort.length < 2) {
            return null;
        } else {
            port = hostAndPort[hostAndPort.length - 1];
            ipAddr = hostAndPortStr.substring(0, hostAndPortStr.lastIndexOf(":"));
        }
        return new HostAndPort(ipAddr, Integer.parseInt(port));
    }
}
